package com.yh.csx.bsf.ods.utils;

/**
 *	全局ID,参考雪花算法
 *	时间(41位)+自增序号(22位)
 * 	@author Robin.Wang
 *  @date	2020-05-13
 * */
public class GlobalIDUtils {
	
	public static long lastTimeStamp;
	public static long sequence;
	private final static long MAX_SEQUENCE = -1L ^ (-1L << 22);
	  /**
     * 	产生下一个ID
     *
     * @return
     */
    public static synchronized long nextId() {
        long currStmp = getNewTimestamp();
        if (currStmp < lastTimeStamp) {
            throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
        }

        if (currStmp == lastTimeStamp) {
            //相同毫秒内，序列号自增
            sequence = (sequence + 1) & MAX_SEQUENCE;
            //同一毫秒的序列数已经达到最大
            if (sequence == 0L) {
                currStmp = getNextMill();
            }
        } else {
            //不同毫秒内，序列号置为0
            sequence = 0;
        }

        lastTimeStamp = currStmp;

        return currStmp << 22 //时间戳部分
                | sequence;   //序列号部分
    }

    private static long getNextMill() {
        long mill = getNewTimestamp();
        while (mill <= lastTimeStamp) {
            mill = getNewTimestamp();
        }
        return mill;
    }

    private static long getNewTimestamp() {
        return System.currentTimeMillis();
    }
}